package com.fowo.api.costAccounting.service.impl;

import com.alibaba.fastjson.JSON;
import com.fowo.api.costAccounting.mapper.CommonCostingMapper;
import com.fowo.api.costAccounting.mapper.MonthlyCostReportMapper;
import com.fowo.api.costAccounting.model.bd.BdAccperiodmonthVo;
import com.fowo.api.costAccounting.model.monthly.MonthlyCostReportItemVo;
import com.fowo.api.costAccounting.model.monthly.MonthlyVo;
import com.fowo.api.costAccounting.model.stock.StockInMonthlyVo;
import com.fowo.api.costAccounting.service.CostAccountingTableService;
import com.fowo.api.costAccounting.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tech.tablesaw.api.Table;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

@Service
@Slf4j
public class CostAccountingTableServiceImpl implements CostAccountingTableService {

    @Autowired
    private MonthlyCostReportMapper monthlyCostReportMapper;
    @Autowired
    private CommonCostingMapper commonCostingMapper;

    @Override
    public void updateMonthlyCostReportTable(String type) throws Exception {
        System.out.println("开始时间--"+new Date());
        // 配置得查询
//        AccountingConfigVo accountingConfigVo= accountingConfigService.getVoById(id);
//        if(accountingConfigVo==null){
//            throw new Exception("暂未找到配置");
//        }
        //获取会计月份bd_accperiodmonth  是否当前会计期 获取对应的数据 如果多条没有直接报错
        //是否需要会计的内码查询过滤？？
        //组织+物料
        //List<BdAccperiodmonthVo> bdAccperiodmonthVoList=bdAccperiodmonthMapper.getByIsCurrentAccperiod();
        List<BdAccperiodmonthVo> bdAccperiodmonthVoList= commonCostingMapper.getByStatus();
        if(bdAccperiodmonthVoList.size()==0||bdAccperiodmonthVoList.size()>1){
            throw new Exception("会计月份查出多条或没有符合得数据");
        }
        if(bdAccperiodmonthVoList.get(0).getBeginDate()==null||bdAccperiodmonthVoList.get(0).getEndDate()==null){
            throw new Exception("会计月份开始时间结束日期未设置");
        }
        if("1".equals(type)){
            typeOneThreadTable(type,bdAccperiodmonthVoList.get(0));
        }else if("2".equals(type)){
            //2 - 组织+仓库+物料
            //typeTwoThread(type,bdAccperiodmonthVoList.get(0));
        }else if("3".equals(type)){
            //2 - 组织+店铺+物料
            // typeThreeThread(type,bdAccperiodmonthVoList.get(0));
        }else {
            //  - 组织+店铺+物料+fnsku  店铺可能为空，fnsku可能为空 暂未设置
            throw  new Exception("类型不对");
        }
    }
    public void typeOneThreadTable(String type,BdAccperiodmonthVo bdAccperiodmonthVo) throws Exception{
        Date start1=new Date();
        //List<MonthlyCostReportItemVo> monthlyCostReportItemVos= monthlyCostReportMapper.getByNowData(type,bdAccperiodmonthVo.getBeginDate(),bdAccperiodmonthVo.getEndDate());
        //入库的
        List<StockInMonthlyVo> stockInMonthlyVoList =commonCostingMapper.getStockInList(type,bdAccperiodmonthVo.getBeginDate(),bdAccperiodmonthVo.getEndDate());
        //成本的
        List<MonthlyCostReportItemVo> monthlyCostReportItemVos= monthlyCostReportMapper.getByPeriodId(type,bdAccperiodmonthVo.getId());
        //获取对应的
        List<Map> skuList=commonCostingMapper.getSKUPriceList();
        try {
            System.out.println("处理转table--"+new Date());
            String  monthlyCostReportItemString= JSON.toJSONString(monthlyCostReportItemVos) ;
            Table table = Table.read().string(monthlyCostReportItemString, "json");
            String  stockInMonthlyVoListString= JSON.toJSONString(stockInMonthlyVoList) ;
            Table table1 = Table.read().string(stockInMonthlyVoListString, "json");
            System.out.println("处理转tablejieshu--"+new Date());
            String  skuListString= JSON.toJSONString(skuList) ;
            Table table2 = Table.read().string(skuListString, "json");
            List<MonthlyVo> monthlyVoList=new ArrayList<>();
            Table result = table.joinOn("itemId").leftOuter(table1,"itemId");
            Table result1=result.joinOn("itemId").leftOuter(table2,"itemId");
            System.out.println("处理转tablejieshu--"+new Date());
            Date start=new Date();
            result1.forEach(t->{
                //System.out.println(t);
                BigDecimal sumAmount=new BigDecimal(0);
                Integer sumCount=0;
                BigDecimal amount=t.getObject("amount")==null?new BigDecimal(0): new BigDecimal(t.getObject("amount").toString());
                Integer qty=t.getObject("qty")==null?0:Integer.parseInt(t.getObject("qty").toString());
                BigDecimal beginAmount=t.getObject("beginAmount")==null?new BigDecimal(0): new BigDecimal(t.getObject("beginAmount").toString());
                Integer beginQty=t.getObject("beginQty")==null?0:Integer.parseInt(t.getObject("beginQty").toString());
                BigDecimal price=t.getObject("price")==null?new BigDecimal(0): new BigDecimal(t.getObject("price").toString());
                //如果期初金额 0 直接直接入库金额÷入库数量
                if(new BigDecimal(t.getObject("beginAmount").toString()).compareTo(BigDecimal.ZERO)==0){
                    sumAmount= amount;
                    sumCount=  qty;
                }else {
                    sumAmount= amount.add(beginAmount);
                    sumCount=  qty+beginQty;
                }
                // 更新出库单  销售出库单 根据过滤得条件 筛选
                MonthlyVo monthlyVo=new MonthlyVo();
                monthlyVo.setPeriodId(bdAccperiodmonthVo.getId());
                monthlyVo.setId(Long.valueOf(t.getObject("id").toString()));
                // monthlyVo.setOrgId(Long.valueOf(t.getObject("orgId").toString()));
                monthlyVo.setItemId(Long.valueOf(t.getObject("itemId").toString()));
                monthlyVo.setBeginDate(DateUtils.getTimesBegin(bdAccperiodmonthVo.getBeginDate()));
                monthlyVo.setEndDate(DateUtils.getTimesEnd(bdAccperiodmonthVo.getEndDate()));
                if(sumCount==0){
                    monthlyVo.setAmount(price);
//                    BigDecimal weightedAverage= commonCostingMapper.getSKUPrice(t.getLong("itemId"));
                }else {
                    //计算 当期加权平均价
                    BigDecimal weightedAverage=sumAmount.divide( BigDecimal.valueOf(sumCount),2,BigDecimal.ROUND_HALF_UP);
                    monthlyVo.setAmount(weightedAverage);
                }
                monthlyVoList.add(monthlyVo);

            });
            Date end=new Date();
            System.out.println("处理数据完成-");
            System.out.println(end.getTime()-start.getTime());

            int listSize = monthlyVoList.size();
            int fetchSize = 1000; //900条执行一IC  in orcale最大查询1000
            for (int i = 0; i < monthlyVoList.size(); i += fetchSize) {
                try {
                    if (i + fetchSize > listSize) {        //作用为toIndex最后没有100条数据则剩余几条newList中就装几条
                        fetchSize = listSize - i;
                    }
                    List<MonthlyVo> list = monthlyVoList.subList(i, i + fetchSize);
                    commonCostingMapper.updateStockOutByTypeBatch(list);
                    commonCostingMapper.updateSalesOutboundByTypeBatch(list);
                    //更新成本 成本月报
                    commonCostingMapper.updateMonthlyCostReportBatch(list);
                } catch (Exception e) {
                    log.info("处理失败 ", e);
                }
            }
            Date end1=new Date();
            System.out.println("修改完成-");
            System.out.println( end1.getTime()-start1.getTime());
        }catch (Exception e ){
            e.printStackTrace();
        }

    }
}
